package com.maxlen.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.maxlen.admin.entity.Admin;
import com.maxlen.admin.entity.AdminRole;
import com.maxlen.admin.entity.Role;
import com.maxlen.admin.entity.dto.PageParamDto;
import com.maxlen.admin.entity.vo.AdminRoleVo;
import com.maxlen.admin.entity.vo.RoleVo;
import com.maxlen.admin.mapper.AdminMapper;
import com.maxlen.admin.service.IAdminRoleService;
import com.maxlen.admin.service.IAdminService;
import com.maxlen.admin.service.IRoleService;
import com.maxlen.admin.utils.WrapperUtils;
import com.maxlen.common.utils.CopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 用户表
 */
@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements IAdminService {

    @Autowired
    private IAdminRoleService adminRoleService;

    @Autowired
    private IRoleService roleService;

    /**
     * 根据用户名查询 Admin 表是否存在用户
     * @param username
     * @return
     */
    @Override
    public Admin findAdminByUsername(String username) {
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        return baseMapper.selectOne(wrapper.eq(Admin::getUsername, username));
    }

    @Override
    public Page<Admin> findAllByPage(PageParamDto pageParamDto) {
        Page<Admin> adminPage = new Page<>(pageParamDto.getCurrentPage(), pageParamDto.getPageSize());
        return baseMapper.selectPage(adminPage, WrapperUtils.getWrapper(pageParamDto, Admin.class));
    }

    @Override
    @Transactional
    public boolean add(AdminRoleVo adminRoleVo) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        Admin admin = new Admin(adminRoleVo.getUsername(), passwordEncoder.encode(adminRoleVo.getPassword()));
        int insert = baseMapper.insert(admin);
        if(insert > 0){
            adminRoleService.addByRoleIdList(admin.getId(), adminRoleVo.getRoleId());
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public boolean deleteById(Long id) {
        int delete = baseMapper.deleteById(id);
        if(delete > 0){
            adminRoleService.removeByAdminId(id);
            return true;
        }
        return false;
    }

    @Override
    @Transactional
    public boolean updateById(AdminRoleVo adminRoleVo) {
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        Long adminId = adminRoleVo.getId();
        Admin admin = new Admin();
        admin.setId(adminId);
        admin.setUsername(adminRoleVo.getUsername());
        admin.setPassword(passwordEncoder.encode(adminRoleVo.getPassword()));
        baseMapper.updateById(admin);

        List<Long> roleId = adminRoleVo.getRoleId();
        List<AdminRole> list = adminRoleService.list(new LambdaQueryWrapper<AdminRole>().eq(AdminRole::getAdminId, adminId));

        if(roleId.isEmpty()){
            adminRoleService.removeByAdminId(adminId);
            return true;
        }

        if(list.isEmpty()){
            adminRoleService.addByRoleIdList(adminId, roleId);
            return true;
        }

        for (Long num : roleId) {
            boolean a = false;
            for (AdminRole adminRole : list) {
                if(num.equals(adminRole.getRoleId())){
                    a = true;
                    adminRole.setRoleId(0L);
                }
            }
            if(a == false){
                adminRoleService.save(new AdminRole(adminId, num));
            }
        }
        for (AdminRole adminRole : list) {
            Long aLong = adminRole.getRoleId();
            if(aLong != 0){
                adminRoleService.removeByAdminIdRoleId(adminId, aLong);
            }
        }

        return true;
    }

    @Override
    @Transactional
    public void deleteByIdList(List<Long> multipleId) {
        for (Long num : multipleId) {
            baseMapper.deleteById(num);
            adminRoleService.removeByAdminId(num);
        }
    }

    @Override
    public List<RoleVo> findRoleByAdminId(Long id) {
        List<Role> roleList;
        if(id == -1){
            roleList = roleService.list();
        }else{
            roleList = roleService.findListByAdminId(id);
        }
        return CopyUtils.copyList(roleList, RoleVo.class);
    }

}
